package vistop.ui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagLayout;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.Rectangle;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.List;

import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import vistop.datatypes.Polygon;

import com.jogamp.opengl.util.Animator;

public class UserInterface implements KeyListener {
	
	private Animator animator;
	private JFrame mainFrame;
	private Dimension canvasSize;
	private JoglPanel joglInstance;
	private JPanel container;
	private List<Polygon> polygons;
	
	public UserInterface (List<Polygon> polygons) {
		this.polygons = polygons;
		initialize();
	}
	
	private void initialize() {
		KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        manager.addKeyEventDispatcher(new MyDispatcher());
        Rectangle window = GraphicsEnvironment.getLocalGraphicsEnvironment().
        		getMaximumWindowBounds();
        // ...............................................initialize Main frame
		mainFrame = new JFrame();
		mainFrame.setTitle("Relational Complex Visualiser");
        mainFrame.pack();
        mainFrame.setBounds(window.x+window.width/4,window.y+window.height/4,window.width/2,window.height/2);
        //mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing (WindowEvent e) {
				animator.stop();
				System.exit(0);
			}
		});
        mainFrame.setResizable(true);
          
        Dimension windowD = mainFrame.getSize();
        
        Container containerC = mainFrame.getContentPane();
        container = new JPanel();
        setSize(container, windowD);
        //container.setLayout(new GridBagLayout());
        container.setLayout(new BorderLayout());
        
        JScrollPane mainScroll = new JScrollPane();
        mainScroll.setViewportView(container);
        containerC.add(BorderLayout.CENTER,container);
        
		// ...............................................initialize jogl panel
		canvasSize = new Dimension(windowD.width, windowD.height);
		
		GLProfile glp = GLProfile.getDefault();
        GLCapabilities caps = new GLCapabilities(glp);
        GLCanvas canvas = new GLCanvas(caps);
        
        JPanel joglPane = new JPanel();
        joglPane.add(canvas);
        joglPane.requestFocusInWindow();
        joglPane.addKeyListener(this);
        joglInstance = new JoglPanel(this);
        canvas.addGLEventListener(joglInstance);
        
        animator = new Animator(canvas);
        animator.start();
		
		setSize(joglPane, canvasSize);
		setSize(canvas, canvasSize);
		container.add(joglPane);
		TextField querySpec = new TextField();
		querySpec.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				System.out.println("Query-Action!");
			}
		});
		containerC.add(BorderLayout.SOUTH,querySpec);
		TextField connectionSpec = new TextField("localhost:8657");
		connectionSpec.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				System.out.println("Connect-Action!");
			}
		});
		containerC.add(BorderLayout.NORTH,connectionSpec);
	}

	public Dimension getCanvasSize() {
		return canvasSize;
	}

	public void show() {
		mainFrame.setVisible(true);
	}
	
	public static void setSize (Component c, Dimension d) {
		c.setSize(d);
		c.setPreferredSize(d);
		c.setMaximumSize(d);
		c.setMinimumSize(d);
	}
	
	
	@Override
	public void keyPressed(KeyEvent key) {
		switch (key.getKeyCode()) {
		case KeyEvent.VK_UP: // rot x+
			joglInstance.rotateCamera(1, 0);
			break;
		case KeyEvent.VK_DOWN: // rot x-
			joglInstance.rotateCamera(-1, 0);
			break;
		case KeyEvent.VK_LEFT: //rot y-
			joglInstance.rotateCamera(0, -1);
			break;
		case KeyEvent.VK_RIGHT: // rot y+
			joglInstance.rotateCamera(0, 1);
			break;
		case KeyEvent.VK_PLUS:
		case KeyEvent.VK_PAGE_UP:
		case KeyEvent.VK_2:
		case KeyEvent.VK_NUMPAD2: // zoom in
			joglInstance.zoomCamera(1);
			break;
		case KeyEvent.VK_MINUS:
		case KeyEvent.VK_PAGE_DOWN:
		case KeyEvent.VK_1:
		case KeyEvent.VK_NUMPAD1:	// zoom out
			joglInstance.zoomCamera(-1);
			break;
		case KeyEvent.VK_0:
		case KeyEvent.VK_NUMPAD0:
			joglInstance.resetCamPos();
			break;
		case KeyEvent.VK_ESCAPE:
			System.exit(0);
			break;
		default:
			break;
		}
		
	}

	@Override
	public void keyReleased(KeyEvent key) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void keyTyped(KeyEvent key) {
		keyPressed(key);
	}
	
	public List<Polygon> getPolygons() {
		return this.polygons;
	}
	
	
	private class MyDispatcher implements KeyEventDispatcher {
        @Override
        public boolean dispatchKeyEvent(KeyEvent e) {
            if (e.getID() == KeyEvent.KEY_PRESSED) {
            	keyPressed(e);
            } else if (e.getID() == KeyEvent.KEY_RELEASED) {
                keyReleased(e);
            } else if (e.getID() == KeyEvent.KEY_TYPED) {
                keyTyped(e);
            }
            return false;
        }
    }
	
}
